package com.qg.auth.handler.impl;

import com.alibaba.fastjson.JSONObject;
import com.qg.auth.handler.WebContextHandler;
import com.qg.auth.util.JwtUtil;
import com.qg.base.constants.WebConstant;
import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.UUID;

/**
 * @Author QG
 * @Date 2023/5/25 15:01
 * @description
 **/
@Component("webContextHandler")
@ConditionalOnBean(RedisTemplate.class)
@ConditionalOnProperty(name = "system.login.method", havingValue = "redis_jwt", matchIfMissing = false)
public class WebContextJwtRedis implements WebContextHandler {

    private static final Logger logger = LoggerFactory.getLogger(WebContextJwtRedis.class);

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${spring.application.name:app}")
    private String APP_NAME;

    private final String PREFIX_USER = "user:";

    @Override
    public <T> T getUser(Class<T> clazz) throws Exception {
        String token = getTokenString(getRequest());
        if(token == null) {
            throw new RuntimeException("user is empty");
        }
        Claims claims = JwtUtil.parseJWT(token);
        T t = JSONObject.parseObject(claims.getSubject(), clazz);
        return t;
    }

    @Override
    public Map getUser() throws Exception {
        String token = getTokenString(getRequest());
        if(token == null) {
            return null;
        }
        String subject = JwtUtil.parseJWT(token).getSubject();
        return JSONObject.parseObject(subject, Map.class);
    }

    @Override
    public String getTokenString(HttpServletRequest request) {
        if(request == null) {
            request = getRequest();
        }
        String flag = request.getHeader(WebConstant.TOKEN);
        String key = PREFIX_USER + APP_NAME + ":" + flag;
        String token = (String) redisTemplate.opsForValue().get(key);
        return token;
    }

    @Override
    public String setUser(Object user) {
        String flag = UUID.randomUUID().toString().substring(0, 8);
        String key = PREFIX_USER + APP_NAME + ":" + flag;
        String jwt = JwtUtil.createJWT(JSONObject.toJSONString(user));
        redisTemplate.opsForValue().set(key,jwt);
        return flag;
    }

    @Override
    public void setUser(String token) {
        logger.debug("该方法尚未实现，目前为空实现");
    }

    @Override
    public void removeUser() {
        String sessionId = getSession().getId();
        String key = PREFIX_USER + APP_NAME + ":" + sessionId;
        redisTemplate.delete(key);
    }
}
